/**
 * this 隐式绑定规则
 * 每个函数在执行的时候都会有自身的this
 * 1、谁调用，this指向谁
 * 2、独立调用，直接指向window
 * 3、立即执行函数，直接指向window(严格模式除外)
 */
var a = 0
var obj = {
    a: 2,
    foo: function(){
        console.log(this, 1);

        function test(){
            console.log(this, 2);
        }

        test(); // 独立调用，直接指向window
        
        // 立即执行函数，this直接指向window(严格模式除外)
        (function(){
            console.log(this, 3);
        })();
    }
}

obj.foo();// 谁调用this指向谁

// 立即执行函数，this直接指向window(严格模式除外)
(function(){
    console.log(this, 4);
}());

// 闭包
// 当函数执行的时候，导致函数被定义，并抛出
var obj1 = {
    a: 2,
    foo: function(){
        console.log(this);
        
        function test(){
            console.log(this);
        }
        
        return test
    }
}

obj1.foo()(); // ==> test() 独立调用，this执行window

var a1 = 0;
function foo() {
    console.log(this, 'obj2');
}

var obj2 = {
    a: 2,
    foo: foo
}

obj2.foo();
// 隐式丢失
// 变量赋值的情况
var bar = obj2.foo // var bar = function foo(){console.log(this)}
bar(); // 直接调用

// 参数赋值的情况
var a11 = 0;
function foo11(){
    console.log(this, 'obj11');
}

function bar11(fn){
    // fn()

    // 父函数有能力决定子函数的this指向
    fn()
    // new fn() // 实例之后的对象
    // fn.bind(obj11)() // 强行指定this
}

var obj11 = {
    a11: 2,
    foo11: foo11 
}

bar11(obj11.foo11)

// 父函数有能力决定子函数的this指向
var arr11 = [1,2,3]
var arr122 = [3,5,6]
arr11.forEach(function(item, inx, arr){
    console.log(this,item,  'a');
})

arr11.sort(function(a, b){
    console.log(this, 'b')
    return a- b
})

setInterval(function(){
    console.log(this, 'c')
}, 2000)